package temp;

import entity.BranchAddressEntity;
import entity.FnBBranchEntity;
import entity.StakeholderEntity;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.model.SelectItem;
import session.stateless.BranchSessionBean;
import session.stateless.SystemMessagesLocal;
import util.enumeration.CuisineType;
import util.enumeration.OperatingDay;
import util.enumeration.OperatingHours;
import util.enumhelper.OperatingHrs;
import util.localization.WebLocalization;


@ManagedBean
@ViewScoped
public class AddBranchManagedBean_1 implements Serializable {

    @EJB
    private BranchSessionBean branchSessionBean;
    //Exception
    @EJB
    private SystemMessagesLocal systemMessages;
    //User Selected Locale
    private String preferredLocale;
    private WebLocalization localization;
    
    //private Branch branch;
    private FnBBranchEntity fnbBranch;
    private StakeholderEntity stakeholder;
    private OperatingDay[] operatingDay = OperatingDay.values();
    private OperatingHours mondayStart;
    private OperatingHours mondayEnd;
    private OperatingHours tuesdayStart;
    private OperatingHours tuesdayEnd;
    private OperatingHours wednesdayStart;
    private OperatingHours wednesdayEnd;
    private OperatingHours thursdayStart;
    private OperatingHours thursdayEnd;
    private OperatingHours fridayStart;
    private OperatingHours fridayEnd;
    private OperatingHours saturdayStart;
    private OperatingHours saturdayEnd;
    private OperatingHours sundayStart;
    private OperatingHours sundayEnd;
    private OperatingHours extendedTimeStart;
    private OperatingHours extendedTimeEnd;
    private List<OperatingHrs> operatingHrsList;
    private List<OperatingHrs> extendedOperatingHoursList;
    //TODO: swee zhi
    private List<CuisineType> cuisineTypeList;
    private SelectItem[] cuisineTypeSelectItems;
    private SelectItem[] fnbTypeSelectItems;
    private SelectItem[] isHalalSelectItems;
    private SelectItem[] priceRangeSelectItems;
    private SelectItem[] operatingDaySelectItems;
    private SelectItem[] mondayStartSelectItems;
    private SelectItem[] mondayEndSelectItems;
    private SelectItem[] tuesdayStartSelectItems;
    private SelectItem[] tuesdayEndSelectItems;
    private SelectItem[] wednesdayStartSelectItems;
    private SelectItem[] wednesdayEndSelectItems;
    private SelectItem[] thursdayStartSelectItems;
    private SelectItem[] thursdayEndSelectItems;
    private SelectItem[] fridayStartSelectItems;
    private SelectItem[] fridayEndSelectItems;
    private SelectItem[] saturdayStartSelectItems;
    private SelectItem[] saturdayEndSelectItems;
    private SelectItem[] sundayStartSelectItems;
    private SelectItem[] sundayEndSelectItems;
    private SelectItem[] extendedTimeStartSelectItems;
    private SelectItem[] extendedTimeEndSelectItems;
    private Date extendedCalendarDate;
    private boolean branchAdded;
    private String operatingHoursRemarks;

    public AddBranchManagedBean_1() {
        /* LOCALIZATION */
        localization = new WebLocalization();
        preferredLocale = localization.getPreferredLocaleFromSession();
        /* END LOCALIZATION */
    }

    /***************************************************\
    /*************** GET SET METHODS *******************\
    /***************************************************/
    public FnBBranchEntity getFnbBranch() {
        return fnbBranch;
    }

    public void setFnbBranch(FnBBranchEntity fnbBranch) {
        this.fnbBranch = fnbBranch;
    }

    public OperatingHours getMondayStart() {
        return mondayStart;
    }

    public void setMondayStart(OperatingHours mondayStart) {
        this.mondayStart = mondayStart;
    }

    public OperatingHours getMondayEnd() {
        return mondayEnd;
    }

    public void setMondayEnd(OperatingHours mondayEnd) {
        this.mondayEnd = mondayEnd;
    }

    public OperatingHours getTuesdayStart() {
        return tuesdayStart;
    }

    public void setTuesdayStart(OperatingHours tuesdayStart) {
        this.tuesdayStart = tuesdayStart;
    }

    public OperatingHours getTuesdayEnd() {
        return tuesdayEnd;
    }

    public void setTuesdayEnd(OperatingHours tuesdayEnd) {
        this.tuesdayEnd = tuesdayEnd;
    }

    public OperatingHours getWednesdayStart() {
        return wednesdayStart;
    }

    public void setWednesdayStart(OperatingHours wednesdayStart) {
        this.wednesdayStart = wednesdayStart;
    }

    public OperatingHours getWednesdayEnd() {
        return wednesdayEnd;
    }

    public void setWednesdayEnd(OperatingHours wednesdayEnd) {
        this.wednesdayEnd = wednesdayEnd;
    }

    public OperatingHours getThursdayStart() {
        return thursdayStart;
    }

    public void setThursdayStart(OperatingHours thursdayStart) {
        this.thursdayStart = thursdayStart;
    }

    public OperatingHours getThursdayEnd() {
        return thursdayEnd;
    }

    public void setThursdayEnd(OperatingHours thursdayEnd) {
        this.thursdayEnd = thursdayEnd;
    }

    public OperatingHours getFridayStart() {
        return fridayStart;
    }

    public void setFridayStart(OperatingHours fridayStart) {
        this.fridayStart = fridayStart;
    }

    public OperatingHours getFridayEnd() {
        return fridayEnd;
    }

    public void setFridayEnd(OperatingHours fridayEnd) {
        this.fridayEnd = fridayEnd;
    }

    public OperatingHours getSaturdayStart() {
        return saturdayStart;
    }

    public void setSaturdayStart(OperatingHours saturdayStart) {
        this.saturdayStart = saturdayStart;
    }

    public OperatingHours getSaturdayEnd() {
        return saturdayEnd;
    }

    public void setSaturdayEnd(OperatingHours saturdayEnd) {
        this.saturdayEnd = saturdayEnd;
    }

    public OperatingHours getSundayStart() {
        return sundayStart;
    }

    public void setSundayStart(OperatingHours sundayStart) {
        this.sundayStart = sundayStart;
    }

    public OperatingHours getSundayEnd() {
        return sundayEnd;
    }

    public void setSundayEnd(OperatingHours sundayEnd) {
        this.sundayEnd = sundayEnd;
    }

    public OperatingHours getExtendedTimeStart() {
        return extendedTimeStart;
    }

    public void setExtendedTimeStart(OperatingHours extendedTimeStart) {
        this.extendedTimeStart = extendedTimeStart;
    }

    public OperatingHours getExtendedTimeEnd() {
        return extendedTimeEnd;
    }

    public void setExtendedTimeEnd(OperatingHours extendedTimeEnd) {
        this.extendedTimeEnd = extendedTimeEnd;
    }

    public List<OperatingHrs> getOperatingHrsList() {
        return operatingHrsList;
    }

    public void setOperatingHrsList(List<OperatingHrs> operatingHrsList) {
        this.operatingHrsList = operatingHrsList;
    }

    public List<OperatingHrs> getExtendedOperatingHoursList() {
        return extendedOperatingHoursList;
    }

    public void setExtendedOperatingHoursList(List<OperatingHrs> extendedOperatingHoursList) {
        this.extendedOperatingHoursList = extendedOperatingHoursList;
    }

    public List<CuisineType> getCuisineTypeList() {
        return cuisineTypeList;
    }

    public void setCuisineTypeList(List<CuisineType> cuisineTypeList) {
        this.cuisineTypeList = cuisineTypeList;
    }

    public SelectItem[] getCuisineTypeSelectItems() {
        return cuisineTypeSelectItems;
    }

    public void setCuisineTypeSelectItems(SelectItem[] cuisineTypeSelectItems) {
        this.cuisineTypeSelectItems = cuisineTypeSelectItems;
    }

    public SelectItem[] getFnbTypeSelectItems() {
        return fnbTypeSelectItems;
    }

    public void setFnbTypeSelectItems(SelectItem[] fnbTypeSelectItems) {
        this.fnbTypeSelectItems = fnbTypeSelectItems;
    }

    public SelectItem[] getIsHalalSelectItems() {
        return isHalalSelectItems;
    }

    public void setIsHalalSelectItems(SelectItem[] isHalalSelectItems) {
        this.isHalalSelectItems = isHalalSelectItems;
    }

    public SelectItem[] getPriceRangeSelectItems() {
        return priceRangeSelectItems;
    }

    public void setPriceRangeSelectItems(SelectItem[] priceRangeSelectItems) {
        this.priceRangeSelectItems = priceRangeSelectItems;
    }

    public SelectItem[] getOperatingDaySelectItems() {
        return operatingDaySelectItems;
    }

    public void setOperatingDaySelectItems(SelectItem[] operatingDaySelectItems) {
        this.operatingDaySelectItems = operatingDaySelectItems;
    }

    public SelectItem[] getMondayStartSelectItems() {
        return mondayStartSelectItems;
    }

    public void setMondayStartSelectItems(SelectItem[] mondayStartSelectItems) {
        this.mondayStartSelectItems = mondayStartSelectItems;
    }

    public SelectItem[] getMondayEndSelectItems() {
        return mondayEndSelectItems;
    }

    public void setMondayEndSelectItems(SelectItem[] mondayEndSelectItems) {
        this.mondayEndSelectItems = mondayEndSelectItems;
    }

    public SelectItem[] getTuesdayStartSelectItems() {
        return tuesdayStartSelectItems;
    }

    public void setTuesdayStartSelectItems(SelectItem[] tuesdayStartSelectItems) {
        this.tuesdayStartSelectItems = tuesdayStartSelectItems;
    }

    public SelectItem[] getTuesdayEndSelectItems() {
        return tuesdayEndSelectItems;
    }

    public void setTuesdayEndSelectItems(SelectItem[] tuesdayEndSelectItems) {
        this.tuesdayEndSelectItems = tuesdayEndSelectItems;
    }

    public SelectItem[] getWednesdayStartSelectItems() {
        return wednesdayStartSelectItems;
    }

    public void setWednesdayStartSelectItems(SelectItem[] wednesdayStartSelectItems) {
        this.wednesdayStartSelectItems = wednesdayStartSelectItems;
    }

    public SelectItem[] getWednesdayEndSelectItems() {
        return wednesdayEndSelectItems;
    }

    public void setWednesdayEndSelectItems(SelectItem[] wednesdayEndSelectItems) {
        this.wednesdayEndSelectItems = wednesdayEndSelectItems;
    }

    public SelectItem[] getThursdayStartSelectItems() {
        return thursdayStartSelectItems;
    }

    public void setThursdayStartSelectItems(SelectItem[] thursdayStartSelectItems) {
        this.thursdayStartSelectItems = thursdayStartSelectItems;
    }

    public SelectItem[] getThursdayEndSelectItems() {
        return thursdayEndSelectItems;
    }

    public void setThursdayEndSelectItems(SelectItem[] thursdayEndSelectItems) {
        this.thursdayEndSelectItems = thursdayEndSelectItems;
    }

    public SelectItem[] getFridayStartSelectItems() {
        return fridayStartSelectItems;
    }

    public void setFridayStartSelectItems(SelectItem[] fridayStartSelectItems) {
        this.fridayStartSelectItems = fridayStartSelectItems;
    }

    public SelectItem[] getFridayEndSelectItems() {
        return fridayEndSelectItems;
    }

    public void setFridayEndSelectItems(SelectItem[] fridayEndSelectItems) {
        this.fridayEndSelectItems = fridayEndSelectItems;
    }

    public SelectItem[] getSaturdayStartSelectItems() {
        return saturdayStartSelectItems;
    }

    public void setSaturdayStartSelectItems(SelectItem[] saturdayStartSelectItems) {
        this.saturdayStartSelectItems = saturdayStartSelectItems;
    }

    public SelectItem[] getSaturdayEndSelectItems() {
        return saturdayEndSelectItems;
    }

    public void setSaturdayEndSelectItems(SelectItem[] saturdayEndSelectItems) {
        this.saturdayEndSelectItems = saturdayEndSelectItems;
    }

    public SelectItem[] getSundayStartSelectItems() {
        return sundayStartSelectItems;
    }

    public void setSundayStartSelectItems(SelectItem[] sundayStartSelectItems) {
        this.sundayStartSelectItems = sundayStartSelectItems;
    }

    public SelectItem[] getSundayEndSelectItems() {
        return sundayEndSelectItems;
    }

    public void setSundayEndSelectItems(SelectItem[] sundayEndSelectItems) {
        this.sundayEndSelectItems = sundayEndSelectItems;
    }

    public SelectItem[] getExtendedTimeStartSelectItems() {
        return extendedTimeStartSelectItems;
    }

    public void setExtendedTimeStartSelectItems(SelectItem[] extendedTimeStartSelectItems) {
        this.extendedTimeStartSelectItems = extendedTimeStartSelectItems;
    }

    public SelectItem[] getExtendedTimeEndSelectItems() {
        return extendedTimeEndSelectItems;
    }

    public void setExtendedTimeEndSelectItems(SelectItem[] extendedTimeEndSelectItems) {
        this.extendedTimeEndSelectItems = extendedTimeEndSelectItems;
    }

    public Date getExtendedCalendarDate() {
        return extendedCalendarDate;
    }

    public void setExtendedCalendarDate(Date extendedCalendarDate) {
        this.extendedCalendarDate = extendedCalendarDate;
    }

    /************************************************************************************\
    /*********************************** METHODS ****************************************\
    /************************************************************************************/
    // TODO: make initview read from enum and not hardcoded lol
    public void initView(PhaseEvent event) {
        FacesContext.getCurrentInstance().getExternalContext().getSession(true);
        /*
        if (stakeholder == null) {
        stakeholder = (StakeholderEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("stakeholderEntity");
        }*/
        //Clear previous set messages(delete)
        FacesContext.getCurrentInstance().getExternalContext().getFlash().clear();

        if (getFnbBranch() == null) {
            setFnbBranch(new FnBBranchEntity());
            getFnbBranch().setBranchAddress(new BranchAddressEntity());

            this.setExtendedOperatingHoursList(new ArrayList<OperatingHrs>());
            this.setCuisineTypeList(new ArrayList<CuisineType>());
            this.setOperatingHrsList(new ArrayList<OperatingHrs>());

            //TODO: swee zhi == i loaded this from enumCuisineType
            //Enum values are mapped onto selectItems which is displayed on AddBranch.xhtml
//            CuisineType[] cuisineTypes = CuisineType.values();
//            EnumCuisineType enumCuisineType = new EnumCuisineType();
//            CuisineType[] cuisineTypes = (CuisineType[]) enumCuisineType.getListItems().toArray();
//            setCuisineTypeSelectItems(new SelectItem[cuisineTypes.length]);
//            for (int i = 0; i < cuisineTypes.length; i++) {
//                getCuisineTypeSelectItems()[i] = new SelectItem(cuisineTypes[i], cuisineTypes[i].toString());
//            }
            

            //TODO: swee zhi == i made this loaded from enumFnbType
            //Enum values are mapped onto selectItems which is displayed on AddBranch.xhtml
//            FnbType[] fnbTypes = FnbType.values();
//            setFnbTypeSelectItems(new SelectItem[fnbTypes.length]);
//            for (int i = 0; i < fnbTypes.length; i++) {
//                if (i == 0) {
//                    //Set no select option = True for first value of FnbType Enum Class (SELECT)
//                    getFnbTypeSelectItems()[i] = new SelectItem(fnbTypes[i], fnbTypes[i].toString(), "", false, false, true);
//                } else {
//                    getFnbTypeSelectItems()[i] = new SelectItem(fnbTypes[i], fnbTypes[i].toString());
//                }
//            }

            //Enum values are mapped onto selectItems which is displayed on AddBranch.xhtml
            OperatingHours[] operatingHours = OperatingHours.values();
            setMondayStartSelectItems(new SelectItem[operatingHours.length]);
            setMondayEndSelectItems(new SelectItem[operatingHours.length]);
            setTuesdayStartSelectItems(new SelectItem[operatingHours.length]);
            setTuesdayEndSelectItems(new SelectItem[operatingHours.length]);
            setWednesdayStartSelectItems(new SelectItem[operatingHours.length]);
            setWednesdayEndSelectItems(new SelectItem[operatingHours.length]);
            setThursdayStartSelectItems(new SelectItem[operatingHours.length]);
            setThursdayEndSelectItems(new SelectItem[operatingHours.length]);
            setFridayStartSelectItems(new SelectItem[operatingHours.length]);
            setFridayEndSelectItems(new SelectItem[operatingHours.length]);
            setSaturdayStartSelectItems(new SelectItem[operatingHours.length]);
            setSaturdayEndSelectItems(new SelectItem[operatingHours.length]);
            setSundayStartSelectItems(new SelectItem[operatingHours.length]);
            setSundayEndSelectItems(new SelectItem[operatingHours.length]);
            setExtendedTimeStartSelectItems(new SelectItem[operatingHours.length]);
            setExtendedTimeEndSelectItems(new SelectItem[operatingHours.length]);

            for (int i = 0; i < operatingHours.length; i++) {
                getMondayStartSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getMondayEndSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getTuesdayStartSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getTuesdayEndSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getWednesdayStartSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getWednesdayEndSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getThursdayStartSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getThursdayEndSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getFridayStartSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getFridayEndSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getSaturdayStartSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getSaturdayEndSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getSundayStartSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getSundayEndSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getExtendedTimeStartSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
                getExtendedTimeEndSelectItems()[i] = new SelectItem(operatingHours[i], operatingHours[i].getLabel());
            }

            // TODO: make yes/no ENUM
            setIsHalalSelectItems(new SelectItem[2]);
            getIsHalalSelectItems()[0] = new SelectItem("Yes", "Yes");
            getIsHalalSelectItems()[1] = new SelectItem("No", "No");

            // TODO: make price range ENUM
            setPriceRangeSelectItems(new SelectItem[7]);
            //Set no select option = True
            getPriceRangeSelectItems()[0] = new SelectItem("SELECT", "SELECT", "", false, false, true);
            getPriceRangeSelectItems()[1] = new SelectItem("Less Than $20", "Less Than $20");
            getPriceRangeSelectItems()[2] = new SelectItem("$21 - $40", "$21 - $40");
            getPriceRangeSelectItems()[3] = new SelectItem("$41 - $60", "$41 - $60");
            getPriceRangeSelectItems()[4] = new SelectItem("$61 - $80", "$61 - $80");
            getPriceRangeSelectItems()[5] = new SelectItem("$81 - $100", "$81 - $100");
            getPriceRangeSelectItems()[6] = new SelectItem("More Than $100", "More Than $100");
        }
    }

    // TODO: what is the use of reset()?
    /*Reset the values of all the fields after adding into the database*/
    public void reset() {
        getFnbBranch().setBranchName("");
        getFnbBranch().getBranchAddress().setStreetName("");
        getFnbBranch().getBranchAddress().setUnitNumber("");
        getFnbBranch().getBranchAddress().setHouseNumber("");
        getFnbBranch().getBranchAddress().setPostalCode(0);
        getFnbBranch().getBranchAddress().setBuildingName("");
        getFnbBranch().setEmailAddress("");
        getFnbBranch().setContactNumber("");
        getFnbBranch().setContactPerson("");
        //getFnbBranch().setOperatingHoursRemarks("");
        cuisineTypeList.clear();
        // TODO: u might need to uncomment this
        //getFnbBranch().setFnBTypeEnum(FnbType.SELECT);
        //getFnbBranch().setIsHalalEnum("");
        //getFnbBranch().setPriceRangeEnum("SELECT");
        setMondayStart(OperatingHours.EightAM);
        setMondayEnd(OperatingHours.EightAM);
        setTuesdayStart(OperatingHours.EightAM);
        setTuesdayEnd(OperatingHours.EightAM);
        setWednesdayStart(OperatingHours.EightAM);
        setWednesdayEnd(OperatingHours.EightAM);
        setThursdayStart(OperatingHours.EightAM);
        setThursdayEnd(OperatingHours.EightAM);
        setFridayStart(OperatingHours.EightAM);
        setFridayEnd(OperatingHours.EightAM);
        setSaturdayStart(OperatingHours.EightAM);
        setSaturdayEnd(OperatingHours.EightAM);
        setSundayStart(OperatingHours.EightAM);
        setSundayEnd(OperatingHours.EightAM);
        setExtendedCalendarDate(null);
        setExtendedTimeStart(OperatingHours.EightAM);
        setExtendedTimeEnd(OperatingHours.EightAM);
        extendedOperatingHoursList.clear();
    }

    //Add a specific date list for extended operating hours
    public void addSpecificDateList() {
        String day = "";
        OperatingHrs specificOperatingHrs = new OperatingHrs();
        boolean duplicate = false;

        //Check calendar date is empty or not
        if (extendedCalendarDate != null) {
            Date todayDate = new Date();
            //entered calendar date has to be after today's date
            if (extendedCalendarDate.before(todayDate) && !(extendedCalendarDate.equals(todayDate))) {
                //String statusMessage = systemMessages.getSystemMessage("TOURIST_ACCT_DOES_NOT_EXIST", preferredLocale);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Extended Date must not be before Today's date", "Extended Date must be after Today's date"));
            } else {
                //check whether the time entered is equal except for off
                if (extendedTimeStart.getTime().equals(extendedTimeEnd.getTime())
                        && !(extendedTimeStart.getLabel().equals("OFF") && extendedTimeEnd.getLabel().equals("OFF"))) {
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Extended Operating Hours: Both start time and end time must be different", "Extended Operating Hours: Both start time and end time must be different"));
                } /*else if (extendedTimeStart.getTime().after(extendedTimeEnd.getTime())
                && (!(extendedTimeStart.getLabel().equals("OFF") && !(extendedTimeEnd.getLabel().equals("OFF"))))) {
                //String statusMessage = systemMessages.getSystemMessage("CREATION_SUCCESS", selectedLocale);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Extended Operating Hours: Select an appropriate time range", "Extended Operating Hours: Select an appropriate time range"));
                } */ //check if 1 time is entered off, the other must also be off
                else if ((extendedTimeStart.getLabel().equals("OFF") && !(extendedTimeEnd.getLabel().equals("OFF")))
                        || (!(extendedTimeStart.getLabel().equals("OFF")) && extendedTimeEnd.getLabel().equals("OFF"))) {
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Extended Operating Hours: Both start time and end time must be OFF", "Extended Operating Hours: Both start time and end time must be OFF"));
                } // if all goes well....
                else {
                    //Select the day string value from enum(Compare calendar day(int value) to enum day(int value))
                    for (int i = 0; i < operatingDay.length; i++) {
                        if (extendedCalendarDate.getDay() == operatingDay[i].getDay()) {
                            day = operatingDay[i].getLabel();
                            specificOperatingHrs = new OperatingHrs(operatingDay[i], day, extendedTimeStart, extendedTimeStart.getTime(), extendedTimeEnd, extendedTimeEnd.getTime(), extendedCalendarDate);
                        }
                    }
                    //If there is no record exist in the list, add to arraylist
                    if (extendedOperatingHoursList.isEmpty()) {
                        extendedOperatingHoursList.add(specificOperatingHrs);
                        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Added to list", "Added to list"));
                    } else {
                        //traverse array list to search for duplicate record
                        //if exists, set msg and break from loop
                        for (int i = 0; i < extendedOperatingHoursList.size(); i++) {
                            //Check both dates is equal
                            if (extendedOperatingHoursList.get(i).getSpecificDate().equals(specificOperatingHrs.getSpecificDate())
                                    && ( //check new opening time has to be after closing time
                                    (extendedOperatingHoursList.get(i).getClosingHours().after(specificOperatingHrs.getOpeningHours()))
                                    || //check both opening n closing is equal
                                    (extendedOperatingHoursList.get(i).getOpeningHours().equals(specificOperatingHrs.getOpeningHours())
                                    && extendedOperatingHoursList.get(i).getClosingHours().equals(specificOperatingHrs.getClosingHours())))) {
                                //if all true, return duplicate msg
                                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Duplicate Date", "Duplicate Date"));
                                duplicate = true;
                                break;
                            }
                        }
                        //if there's no duplicate records in arraylist, add new record into list
                        if (duplicate == false) {
                            extendedOperatingHoursList.add(specificOperatingHrs);
                            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Added to list", "Added to list"));
                        }
                    }
                }
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please ensure extended date is selected", "Please ensure extended date is selected"));
        }
    }

    public void removeSpecificDateList(OperatingHrs extendedOperatingHrs) {
        extendedOperatingHoursList.remove(extendedOperatingHrs);
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Removed from list", "Removed from list"));
    }

    public void saveNewBranch() {

        this.operatingHrsList = new ArrayList<OperatingHrs>();

        OperatingHrs monOpHrs = new OperatingHrs(operatingDay[0], operatingDay[0].getLabel(), getMondayStart(), getMondayStart().getTime(), getMondayEnd(), getMondayEnd().getTime());
        OperatingHrs tuesOpHrs = new OperatingHrs(operatingDay[1], operatingDay[1].getLabel(), getTuesdayStart(), getTuesdayStart().getTime(), getTuesdayEnd(), getTuesdayEnd().getTime());
        OperatingHrs wedOpHrs = new OperatingHrs(operatingDay[2], operatingDay[2].getLabel(), getWednesdayStart(), getWednesdayStart().getTime(), getWednesdayEnd(), getWednesdayEnd().getTime());
        OperatingHrs thursOpHrs = new OperatingHrs(operatingDay[3], operatingDay[3].getLabel(), getThursdayStart(), getThursdayStart().getTime(), getThursdayEnd(), getThursdayEnd().getTime());
        OperatingHrs friOpHrs = new OperatingHrs(operatingDay[4], operatingDay[4].getLabel(), getFridayStart(), getFridayStart().getTime(), getFridayEnd(), getFridayEnd().getTime());
        OperatingHrs satOpHrs = new OperatingHrs(operatingDay[5], operatingDay[5].getLabel(), getSaturdayStart(), getSaturdayStart().getTime(), getSaturdayEnd(), getSaturdayEnd().getTime());
        OperatingHrs sunOpHrs = new OperatingHrs(operatingDay[6], operatingDay[6].getLabel(), getSundayStart(), getSundayStart().getTime(), getSundayEnd(), getSundayEnd().getTime());
        getOperatingHrsList().add(monOpHrs);
        getOperatingHrsList().add(tuesOpHrs);
        getOperatingHrsList().add(wedOpHrs);
        getOperatingHrsList().add(thursOpHrs);
        getOperatingHrsList().add(friOpHrs);
        getOperatingHrsList().add(satOpHrs);
        getOperatingHrsList().add(sunOpHrs);


        branchAdded = branchSessionBean.addBranch(getFnbBranch().getBranchName(), getFnbBranch().getBranchAddress().getPostalCode(), getFnbBranch().getBranchAddress().getUnitNumber(), getFnbBranch().getBranchAddress().getHouseNumber(),
                getFnbBranch().getBranchAddress().getStreetName(), getFnbBranch().getBranchAddress().getBuildingName(), getFnbBranch().getContactNumber(), getFnbBranch().getContactPerson(),
                getFnbBranch().getEmailAddress(), getFnbBranch().getFnBTypeEnum(), getFnbBranch().getIsHalalEnum(), getFnbBranch().getPriceRangeEnum(),
                preferredLocale, operatingHoursRemarks, getCuisineTypeList(), getOperatingHrsList(), getExtendedOperatingHoursList() //StakeholderEntity stakeholder
                );

        if (branchAdded == true) {
            //String statusMessage = systemMessages.getSystemMessage("CREATION_SUCCESS", preferredLocale);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Branch: " + getFnbBranch().getBranchName() + " is added successfully", ""));
            reset();
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Branch information is not added successfully.", ""));
        }
    }

    public String getButton() {
        List<FnBBranchEntity> branchList = new ArrayList();
        branchList = branchSessionBean.viewAllBranch();
        if (!branchList.isEmpty()) {
            return "Add More Branches";
        } else {
            return "Add A New Branch";
        }
    }

    /************************************************************************************|
    |*********************************** VALIDATION METHODS *****************************|
    |************************************************************************************/
    public void validateOperatingHours(FacesContext context, UIComponent component, Object value) {
        //Get the specific component ID
        String ID = component.getId();
        //Get the end time of the operating hours
        OperatingHours endTime = (OperatingHours) value;
        //Check the component ID
        if (ID.contains("Monday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
        }
        } else if (ID.contains("Tuesday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
    }
        } else if (ID.contains("Wednesday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
            }
        } else if (ID.contains("Thursday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
            }
        } else if (ID.contains("Friday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
            }
        } else if (ID.contains("Saturday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
            }
        } else if (ID.contains("Sunday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
            }
        }
    }

    public String validateOpHrs(UIComponent component, OperatingHours endTime) {
        UIInput day = (UIInput) component.getAttributes().get("day");
        OperatingHours startTime = (OperatingHours) day.getValue();

        //If either start time of end time is off
        if (startTime.getLabel().equals("OFF") || endTime.getLabel().equals("OFF")) {
            //if confirm both is off
            if (startTime.getLabel().equals("OFF") && endTime.getLabel().equals("OFF")) {
                return "";
            } else {
                //set the component that value is deemed incorrect to false to disallow submitting of page
                ((UIInput) component).setValid(false);
                //return error message
                return "Operating Hours: Both start time and end time must be OFF";
        }
        } else if (startTime.getTime().equals(endTime.getTime())) {
            //set the component that value is deemed incorrect to false to disallow submitting of page
            ((UIInput) component).setValid(false);
            //return error message
            return "Operating Hours: Both start time and end time must be different";
    }
        return "";
}

    public void validateEmail(FacesContext context, UIComponent toValidate, Object value) {
        String email = (String) value;
        Pattern p = Pattern.compile("^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$");

        //Match the given string with the pattern
        Matcher m = p.matcher(email);

        //Check whether match is found
        boolean matchFound = m.matches();

        //if mail does not match the pattern
        if (!matchFound) {
            ((UIInput) toValidate).setValid(false);
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid Email Address", "Invalid Email Address");
            context.addMessage(toValidate.getClientId(context), message);
        }
    }

    public void validateBranchName(FacesContext context, UIComponent toValidate, Object value) {
        String name = (String) value;

        List<FnBBranchEntity> branchExists = branchSessionBean.getFnBBranchList();
        for (int i = 0; i < branchExists.size(); i++) {
            if (branchExists.get(i).getBranchName().equalsIgnoreCase(name)) {
                ((UIInput) toValidate).setValid(false);
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Branch Name: " + branchExists.get(i).getBranchName() + " has already exists", "Branch Name: " + branchExists.get(i).getBranchName() + " has already exists");
                context.addMessage(toValidate.getClientId(context), message);
            }
        }
    }
}
